﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Xml;

namespace NewSeasonFinder
{
    class ShowXml
    {
        /// <summary>
        /// 判断剧集XML文件是否存在
        /// </summary>
        /// <returns>剧集XML文件是否存在</returns>
        public static bool Exist()
        {
            return File.Exists(NameStrings.FILENAME_SHOW);
        }

        /// <summary>
        /// 读取剧集XML文件
        /// </summary>
        public static XmlDocument Read()
        {
            XmlDocument xmlDoc = new XmlDocument();
            if (Exist())
            {
                xmlDoc.Load(NameStrings.FILENAME_SHOW);
            }
            else
            {
                XmlElement xe = xmlDoc.CreateElement(NameStrings.SHOWS);
                xmlDoc.AppendChild(xe);
                xmlDoc.Save(NameStrings.FILENAME_SHOW);
            }

            return xmlDoc;
        }

        /// <summary>
        /// 存储剧集XML文件
        /// </summary>
        public static void Save(XmlDocument _xmlDoc)
        {
            _xmlDoc.Save(NameStrings.FILENAME_SHOW);
        }

        /// <summary>
        /// 获取剧集名字符串
        /// </summary>
        /// <param name="xn_show">剧集Xml节点</param>
        /// <returns>剧集名字符串</returns>
        public static string GetShowFullName(XmlNode xn_show)
        {
            return GetShowFullName(xn_show, " ");
        }

        /// <summary>
        /// 获取剧集名字符串
        /// </summary>
        /// <param name="xn_show">剧集Xml节点</param>
        /// <param name="separateString">主剧集名与子剧集名之间分隔符</param>
        /// <returns>剧集名字符串</returns>
        public static string GetShowFullName(XmlNode xn_show, string separateString)
        {
            string showName = "";

            XmlNode xn_Name = xn_show.SelectSingleNode(NameStrings.NAME);
            XmlNode xn_ChildName = xn_show.SelectSingleNode(NameStrings.CHILDNAMES);

            //获取剧集名
            foreach (XmlNode xn_namestring in xn_Name.ChildNodes)
            {
                showName += xn_namestring.Attributes[NameStrings.VALUE].Value + " ";
            }
            showName = showName.Trim();

            //获取子剧集名
            if (xn_ChildName != null && xn_ChildName.HasChildNodes)
            {
                showName += separateString;
                XmlNode xn_childname = xn_ChildName.FirstChild;
                foreach (XmlNode xn_childnamestring in xn_childname.ChildNodes)
                {
                    showName += xn_childnamestring.Attributes[NameStrings.VALUE].Value + " ";
                }
            }
            showName = showName.Trim();

            return showName;
        }


        /// <summary>
        /// 将剧集按字母顺序排序
        /// </summary>
        public static XmlDocument ShowSort(XmlDocument _xmlDoc)
        {
            XmlNode root = _xmlDoc.FirstChild;
            int n = root.ChildNodes.Count;
            List<string> ShowStringList = new List<string>();

            foreach (XmlNode xn_show in root.ChildNodes)
            {
                ShowStringList.Add(GetShowFullName(xn_show, ": "));
            }

            for (int i = 0; i < n - 1; i++)
            {
                for (int j = 0; j < n - i - 1; j++)
                {
                    if (ShowStringList[j].CompareTo(ShowStringList[j + 1]) > 0)
                    {
                        string temp = ShowStringList[j];
                        ShowStringList[j] = ShowStringList[j + 1];
                        ShowStringList[j + 1] = temp;
                        root.InsertAfter(root.ChildNodes[j], root.ChildNodes[j + 1]);
                    }
                }
            }
            return _xmlDoc;
        }

        /// <summary>
        /// 生成剧集名节点
        /// </summary>
        /// <param name="xmlDoc">XML文档</param>
        /// <param name="showName">剧集名</param>
        /// <returns>剧集名节点</returns>
        private static XmlElement CreateShowNameElement(XmlDocument xmlDoc, string showName)
        {
            char[] splitCharName = { ' ', '.' };

            //创建Element
            XmlNode root = xmlDoc.FirstChild;

            XmlElement xe_showname = xmlDoc.CreateElement(NameStrings.NAME);
            XmlElement xe_namestring = null;
            //获取剧集名
            string[] listShowName = showName.Trim().Split(splitCharName);
            foreach (string strName in listShowName)
            {
                //写入名称字段
                xe_namestring = xmlDoc.CreateElement(NameStrings.NAMESTRING);
                xe_namestring.SetAttribute(NameStrings.VALUE, strName.Trim().ToLower());
                xe_showname.AppendChild(xe_namestring);
            }
            return xe_showname;
        }

        /// <summary>
        /// 生成子剧集名节点
        /// </summary>
        /// <param name="xmlDoc">XML文档</param>
        /// <param name="showName">子剧集名</param>
        /// <returns>剧集名节点</returns>
        private static XmlElement CreateShowChildNameElement(XmlDocument xmlDoc, string showChildNames)
        {
            char[] splitCharName = { ' ', '.' };

            //创建Element
            XmlElement xe_childnames = xmlDoc.CreateElement(NameStrings.CHILDNAMES);
            XmlElement xe_childname = null;

            string[] listChildNames = showChildNames.Trim().Split(new char[] { ';' });

            //写入多个剧集子名称
            foreach (string childName in listChildNames)
            {
                //写入剧集子名称之一
                string[] listChildNameStings = childName.Trim().Split(splitCharName);
                
                //创建Element
                xe_childname = xmlDoc.CreateElement(NameStrings.CHILDNAME);

                XmlElement xe_childNameString = null;
                foreach (string childNameSting in listChildNameStings)
                {
                    //写入名称字段
                    xe_childNameString = xmlDoc.CreateElement(NameStrings.CHILDNAMESTRING);
                    xe_childNameString.SetAttribute(NameStrings.VALUE, childNameSting.Trim().ToLower());
                    xe_childname.AppendChild(xe_childNameString);
                }
                xe_childnames.AppendChild(xe_childname);
            }

            return xe_childnames;
        }

        /// <summary>
        /// 添加剧集
        /// </summary>
        /// <param name="_xmlDoc">存储剧集的XML文档</param>
        /// <param name="showName">主剧集名</param>
        /// <param name="showChildNames">子剧集名(多个用";"分开)</param>
        /// <returns>0: 成功; -1:名称为空; -2:剧集重复;</returns>
        public static int AddShow(XmlDocument _xmlDoc, string showName, string showChildNames)
        {
            if (string.IsNullOrEmpty(showName))
            {
                return -1;
            }

            char[] splitCharName = { ' ', '.' };

            //建立巨集节点
            XmlNode root = _xmlDoc.FirstChild;
            XmlElement xe_show = _xmlDoc.CreateElement(NameStrings.SHOW);

            //插入剧集名称
            xe_show.AppendChild(CreateShowNameElement(_xmlDoc, showName));

            //插入子剧集名称
            if (!string.IsNullOrEmpty(showChildNames))
            {
                xe_show.AppendChild(CreateShowChildNameElement(_xmlDoc, showChildNames));
            }

            //完成添加
            List<string> ShowStringList = new List<string>();

            foreach (XmlNode xn_show in root.ChildNodes)
            {
                ShowStringList.Add(ShowXml.GetShowName(xn_show) + ": " + ShowXml.GetShowChildName(xn_show));
            }

            string showString = ShowXml.GetShowName(xe_show) + ": " + ShowXml.GetShowChildName(xe_show);
            for (int i = 0; i < ShowStringList.Count; i++)
            {
                int result = showString.CompareTo(ShowStringList[i]);
                if (result < 0)
                {
                    root.InsertBefore(xe_show, root.ChildNodes[i]);
                    return 0; //成功
                }
                else if (result == 0)
                {
                    return -2; //重复
                }
            }
            root.AppendChild(xe_show);
            return 0; //成功
        }


        /// <summary>
        /// 删除剧集
        /// </summary>
        /// <param name="_xmlDoc">存储剧集的XML文档</param>
        /// <param name="xn_show">剧集节点</param>
        /// <returns>0: 成功; -3:剧集不存在 </returns>
        public static int DelShow(XmlDocument _xmlDoc, XmlNode xn_show)
        {
            if (xn_show.ParentNode != _xmlDoc.FirstChild)
            {
                return -3;//剧集不存在于Xml文档
            }

            _xmlDoc.FirstChild.RemoveChild(xn_show);
            return 0; //成功
        }


        /// <summary>
        /// 修改剧集
        /// </summary>
        /// <param name="_xmlDoc">存储剧集的XML文档</param>
        /// <param name="xn_show">剧集节点</param>
        /// <param name="showName">主剧集名</param>
        /// <param name="showChildNames">子剧集名(多个用";"分开)</param>
        /// <returns>0: 成功; -1:名称为空; -2:剧集重复; -3:剧集不存在;</returns>
        public static int EditShow(XmlDocument _xmlDoc, XmlNode xn_show, string showName, string showChildNames)
        {
            if (string.IsNullOrEmpty(showName))
            {
                return -1;//名称为空
            }

            if (xn_show.ParentNode != _xmlDoc.FirstChild)
            {
                return -3;//剧集不存在于Xml文档
            }

            char[] splitCharName = { ' ', '.' };

            //建立剧集节点
            XmlNode root = _xmlDoc.FirstChild;
            XmlElement xe_newShowName = _xmlDoc.CreateElement(NameStrings.SHOW);

            //插入剧集名称
            xe_newShowName.AppendChild(CreateShowNameElement(_xmlDoc, showName));

            //插入子剧集名称
            if (!string.IsNullOrEmpty(showChildNames))
            {
                xe_newShowName.AppendChild(CreateShowChildNameElement(_xmlDoc, showChildNames));
            }

            //查询是否重复
            List<string> ShowStringList = new List<string>();
            foreach (XmlNode xn in root.ChildNodes)
            {
                ShowStringList.Add(ShowXml.GetShowName(xn) + ": " + ShowXml.GetShowChildName(xn));
            }

            string showString = ShowXml.GetShowName(xe_newShowName) + ": " + ShowXml.GetShowChildName(xe_newShowName);

            for (int i = 0; i < ShowStringList.Count; i++)
            {
                int result = showString.CompareTo(ShowStringList[i]);
                if (result < 0)
                {
                    root.InsertBefore(xn_show, root.ChildNodes[i]);
                    break;
                }
                else if (result == 0)
                {
                    if (root.ChildNodes[i] != xn_show)
                    {
                        return -2; //重复
                    }
                    break;
                }
            }
            //删除旧剧名
            xn_show.RemoveChild(xn_show.SelectSingleNode(NameStrings.NAME));
            if (xn_show.SelectSingleNode(NameStrings.CHILDNAMES) != null)
            {
                xn_show.RemoveChild(xn_show.SelectSingleNode(NameStrings.CHILDNAMES));
            }
            //添加新剧名
            xn_show.InsertBefore(xe_newShowName.SelectSingleNode(NameStrings.NAME), xn_show.FirstChild);
            if (xe_newShowName.SelectSingleNode(NameStrings.CHILDNAMES) != null)
            {
                xn_show.InsertAfter(xe_newShowName.SelectSingleNode(NameStrings.CHILDNAMES), xn_show.FirstChild);
            }
            return 0; //成功
        }

        /// <summary>
        /// 添加一季
        /// </summary>
        /// <param name="xmlDoc">存储剧集的XML文档</param>
        /// <param name="xn_show">剧集节点</param>
        /// <param name="season">第几季</param>
        /// <returns>0: 成功; -4:该季已存在; -3:剧集不存在;</returns>
        public static int AddSeason(XmlDocument xmlDoc, XmlNode xn_show, int season)
        {
            if (xn_show.ParentNode != xmlDoc.FirstChild)
            {
                return -3;//剧集不存在于Xml文档
            }

            //写入季号
            XmlElement xe_newseason = xmlDoc.CreateElement(NameStrings.SEASON);
            xe_newseason.SetAttribute(NameStrings.VALUE, season.ToString());

            foreach (XmlNode xn_season in xn_show.SelectNodes(NameStrings.SEASON))
            {
                int result = season - Convert.ToInt32(xn_season.Attributes[NameStrings.VALUE].Value);
                if (result == 0)
                {
                    return -4; //重复
                }
                else if (result < 0)
                {
                    xn_show.InsertBefore(xe_newseason, xn_season);
                    return 0; //成功添加
                }
            }
            xn_show.AppendChild(xe_newseason);
            return 0;//成功添加
        }

        /// <summary>
        /// 删除一季
        /// </summary>
        /// <param name="_xmlDoc">存储剧集的XML文档</param>
        /// <param name="xn_show">剧集节点</param>
        /// <param name="season">第几季</param>
        /// <returns>0: 成功; -3:剧集不存在; -5:该季不存在</returns>
        public static int DelSeason(XmlDocument _xmlDoc, XmlNode xn_show, int season)
        {
            XmlDocument xmlDoc = Read();

            if (xn_show.ParentNode != _xmlDoc.FirstChild)
            {
                return -1;//剧集不存在于Xml文档
            }

            //写入季号
            XmlElement xe_newseason = xmlDoc.CreateElement(NameStrings.SEASON);
            xe_newseason.SetAttribute(NameStrings.VALUE, season.ToString());

            foreach (XmlNode xn_season in xn_show.SelectNodes(NameStrings.SEASON))
            {
                int result = season - Convert.ToInt32(xn_season.Attributes[NameStrings.VALUE].Value);
                if (result == 0)
                {
                    xn_show.RemoveChild(xn_season);
                    return 0;//成功删除
                }
                else if (result < 0)
                {
                    break;
                }
            }
            return -5;//该季不存在
        }

        /// <summary>
        /// 添加标记
        /// </summary>
        /// <param name="xmlDoc">存储剧集的XML文档</param>
        /// <param name="xn_season">季节点</param>
        /// <param name="mark">标记</param>
        /// <returns>0: 成功; -4:该标记已存在; -3:剧集不存在;</returns>
        public static int AddMark(XmlDocument xmlDoc, XmlNode xn_season, string mark)
        {
            if (xn_season.ParentNode == null || xn_season.ParentNode.ParentNode != xmlDoc.FirstChild)
            {
                return -3;//季不存在于Xml文档
            }

            //写入标记
            XmlElement xe_newmark = xmlDoc.CreateElement(NameStrings.MARK);
            xe_newmark.SetAttribute(NameStrings.VALUE, mark);

            foreach (XmlNode xn_mark in xn_season.SelectNodes(NameStrings.MARK))
            {
                int result = Convert.ToInt32(mark) - Convert.ToInt32(xn_mark.Attributes[NameStrings.VALUE].Value);
                if (result == 0)
                {
                    return -4; //重复
                }
                else if (result < 0)
                {
                    xn_season.InsertBefore(xe_newmark, xn_mark);
                    return 0; //成功添加
                }
            }
            xn_season.AppendChild(xe_newmark);
            return 0;//成功添加
        }

        /// <summary>
        /// 删除标记
        /// </summary>
        /// <param name="_xmlDoc">存储剧集的XML文档</param>
        /// <param name="xn_season">季节点</param>
        /// <param name="mark">标记</param>
        /// <returns>0: 成功; -3:剧集不存在; -5:该季不存在</returns>
        public static int DelMark(XmlDocument xmlDoc, XmlNode xn_season, string mark)
        {
            if (xn_season.ParentNode == null || xn_season.ParentNode.ParentNode != xmlDoc.FirstChild)
            {
                return -3;//季不存在于Xml文档
            }

            //写入标记
            XmlElement xe_newmark = xmlDoc.CreateElement(NameStrings.MARK);
            xe_newmark.SetAttribute(NameStrings.VALUE, mark);

            foreach (XmlNode xn_mark in xn_season.SelectNodes(NameStrings.MARK))
            {
                int result = Convert.ToInt32(mark) - Convert.ToInt32(xn_mark.Attributes[NameStrings.VALUE].Value);
                if (result == 0)
                {
                    xn_season.RemoveChild(xn_mark);
                    return 0;//成功删除
                }
                else if (result < 0)
                {
                    break;
                }
            }
            return -5;//该标记不存在
        }

        /// <summary>
        /// 获取主剧集名
        /// </summary>
        /// <param name="xn_show">剧集节点</param>
        /// <returns>主剧集名</returns>
        public static string GetShowName(XmlNode xn_show)
        {
            string showName = "";

            XmlNode xn_Name = xn_show.SelectSingleNode(NameStrings.NAME);

            //获取剧集名
            foreach (XmlNode xn_namestring in xn_Name.ChildNodes)
            {
                showName += xn_namestring.Attributes[NameStrings.VALUE].Value + " ";
            }
            showName = showName.Trim();
            return showName;
        }
        
        /// <summary>
        /// 获取子剧集名
        /// </summary>
        /// <param name="xn_show">剧集节点</param>
        /// <returns>子剧集名</returns>
        public static string GetShowChildName(XmlNode xn_show)
        {
            string showChildName = "";

            XmlNode xn_ChildName = xn_show.SelectSingleNode(NameStrings.CHILDNAMES);

            if (xn_ChildName != null)
            {
                foreach (XmlNode xn_childname in xn_ChildName.ChildNodes)
                {
                    foreach (XmlNode xn_childnamestring in xn_childname.ChildNodes)
                    {
                        showChildName += xn_childnamestring.Attributes[NameStrings.VALUE].Value + " ";
                    }
                    showChildName = showChildName.Trim() + "; ";
                }
            }
            showChildName = showChildName.Trim();
            return showChildName;
        }

        /// <summary>
        /// 获取节点季号
        /// </summary>
        /// <param name="xn_season">Xml季节点</param>
        /// <returns>季号</returns>
        public static string GetSeason(XmlNode xn_season)
        {
            return xn_season.Attributes[NameStrings.VALUE].Value;
        }
    }
}
